package cn.fsw.pethome.config;

import cn.fsw.pethome.annotations.PreAuthorize;
import cn.fsw.pethome.jwt.JwtUtils;
import cn.fsw.pethome.jwt.Payload;
import cn.fsw.pethome.jwt.PayloadData;
import cn.fsw.pethome.jwt.RsaUtils;
import cn.fsw.pethome.org.mapper.EmployeeMapper;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.security.PublicKey;
import java.util.Date;
import java.util.Set;

/*springmvc拦截器*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
        @Autowired
        private RedisTemplate redisTemplate;
        @Autowired
        private EmployeeMapper employeeMapper;

        @Value("${jwt.rsa.pub}")
        private String pub;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取请求头
        String token = request.getHeader("token");
        //2.校验token
        if(!StringUtils.isEmpty(token)){
        //3.根据token获取redis的值
        //获取公钥
        PublicKey publicKey = RsaUtils.getPublicKey(JwtUtils.class.getClassLoader().getResource(pub).getFile());
        //解密
        Payload<PayloadData> userinfo = JwtUtils.getInfoFromToken(token, publicKey, PayloadData.class);
        if(userinfo != null){
            //3.2拿不到 刷新token过期时间，放行
            //刷新token
            //过期时间
            Date expiration = userinfo.getExpiration();
            //刷新时间
            DateTime refreshTime = new DateTime(expiration).minusMinutes(5);
            //当前时间在刷新时间之后就要刷新一把
            if(refreshTime.isBefore(DateTime.now())){
                //重新登录刷新token          response.getWriter().write("{\"success\":false,\"message\":\"noLogin\"}");
                return false;
            }

            PayloadData payloadData = userinfo.getUserInfo();
            /*判断是否是普通用户*/
            if(payloadData.getUser() != null){
                return true;
            }
            Set<String> permissions = payloadData.getPermissions();

            HandlerMethod handlerMethod = (HandlerMethod) handler;
            /*获取方法上的注解 并解析*/
            PreAuthorize methodAnnotation = handlerMethod.getMethodAnnotation(PreAuthorize.class);
            if(methodAnnotation == null){
                return true;
            }

            String sn = methodAnnotation.value();
            if(permissions.contains(sn)){
                return true;
            }
                //2.1如果获取不到值返回错误信息
                //3.1拿不到 登录失效返回错误信息
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=UTF-8");
                PrintWriter writer = response.getWriter();
                writer.println("{\"success\":false,\"msg\":\"对不起,您没有权限,请联系管理员\"}");
                writer.flush();
                writer.close();
                return false;
        }
    }
        //2.1如果获取不到值返回错误信息
        //3.1拿不到 登录失效返回错误信息
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.println("{\"success\":false,\"msg\":\"NoLogin\"}");
        writer.flush();
        writer.close();
        return false;

    }

    /*@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取请求头
        String token = request.getHeader("token");
        //2.校验token
        if(!StringUtils.isEmpty(token)){
            //3.根据token获取redis的值
            Object userinfo = redisTemplate.opsForValue().get(token);
            if(userinfo != null){
                //3.2拿不到 刷新token过期时间，放行
                redisTemplate.opsForValue().set(token,userinfo,30, TimeUnit.MINUTES);

                Logininfo logininfo = (Logininfo) userinfo;
                List<String> sns =  employeeMapper.selectBySn(logininfo.getId());
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                *//*获取方法上的注解 并解析*//*
                PreAuthorize methodAnnotation = handlerMethod.getMethodAnnotation(PreAuthorize.class);
                if(methodAnnotation == null){
                    return true;
                }
                String sn = methodAnnotation.value();
                if(sns.contains(sn)){
                    return true;
                }
                //2.1如果获取不到值返回错误信息
                //3.1拿不到 登录失效返回错误信息
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=UTF-8");
                PrintWriter writer = response.getWriter();
                writer.println("{\"success\":false,\"msg\":\"对不起,您没有权限,请联系管理员\"}");
                writer.flush();
                writer.close();
                return false;
            }
        }
        //2.1如果获取不到值返回错误信息
        //3.1拿不到 登录失效返回错误信息
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.println("{\"success\":false,\"msg\":\"NoLogin\"}");
        writer.flush();
        writer.close();
        return false;

    }*/
}